
import json
from django import http
from django.http import JsonResponse
from django.shortcuts import render
# Create your views here.
from django.views import View
from django_redis import get_redis_connection
from apps.carts import models
from apps.goods.models import SKU
from utils.cookiesecret import CookieSecret
from utils.response_code import RETCODE
class CartsSimpleView(View):
    def get(self,request):
        user = request.user
        if user.is_authenticated:
            #redis3
            redis_client = get_redis_connection("carts")
            client_data = redis_client.hgetall(user.id)
            carts_dict = {int(data[0].decode()):json.loads(data[1].decode()) for data in client_data.items()}
        else:
            #cookie5
            cookie_str = request.COOKIES.get("carts")
            if cookie_str:
                carts_dict = CookieSecret.loads(cookie_str)
            else:
                carts_dict = {}
        cart_skus = []
        sku_ids = carts_dict.keys()
        skus = SKU.objects.filter(id__in = sku_ids)
        for sku in skus:
            cart_skus.append({
                "id":sku.id,
                "name":sku.name,
                "count":carts_dict.get(sku.id).get("count"),
                "default_image_url":sku.default_image.url,
            })
        return http.JsonResponse({"code":RETCODE.OK,"errmsg":"OK","cart_skus":cart_skus})
class CartsSelectedView(View):
    def put(self,request):
        selected = json.loads(request.body.decode()).get("selected",True)
        if selected:
            if not isinstance(selected,bool):
                return http.HttpResponseForbidden("selected类型不是布尔类型")
        user = request.user
        cookie_secrect_str = ""
        if user.is_authenticated:
           #1.取所有
            redis_client = get_redis_connection("carts")
            client_data = redis_client.hgetall(user.id)
            for data in client_data.items():
                sku_id = int(data[0].decode())
                sku_dict = json.loads(data[1].decode())
                #修改
                sku_dict["selected"]=selected
                redis_client.hset(user.id,sku_id,json.dumps(sku_dict))
        else:
            cookie_str = request.COOKIES.get("carts")
            if cookie_str is not None:
                cart_dict = CookieSecret.loads(cookie_str)
                for sku_id in cart_dict:
                    cart_dict[sku_id]['selected']=selected
                cookie_secrect_str = CookieSecret.dumps(cart_dict)

        response = JsonResponse({"code":RETCODE.OK,"errmsg":"全选购物车成功"})
        if not user.is_authenticated:
            response.set_cookie("carts",cookie_secrect_str,14*24*3600)
        return response
class CartsView(View):
    def delete(self,request):
        #1.接收sku_id
        sku_id = json.loads(request.body.decode()).get("sku_id")
        # *2.校验
        try:
            sku = SKU.objects.get(id=sku_id)
        except Exception as e:
            return http.HttpResponseForbidden("商品不存在")
        #判断是否登陆
        user = request.user
        cookie_secret_str = ""
        if user.is_authenticated:
            #1.链接redis
            redis_client = get_redis_connection("carts")
            #2.直接修改hdel
            redis_client.hdel(user.id,sku_id)

        else:
            #cookie
            cookie_str = request.COOKIES.get("carts")
            if cookie_str:
                cart_dict = CookieSecret.loads(cookie_str)
            else:
                cart_dict = {}
            if sku_id in cart_dict:
                del cart_dict[sku_id]
            cookie_secret_str = CookieSecret.dumps(cart_dict)
        response = JsonResponse({"code":RETCODE.OK,"errmsg":"删除购物车成功"})
        if not user.is_authenticated:
            response.set_cookie("carts",cookie_secret_str,3600*14*24)
        return response
    def put(self,request):
        #接收参数
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get("sku_id")
        count = json_dict.get("count")
        selected = json_dict.get("selected",True)
        #判断参数是否齐全
        if not all([sku_id,count]):
            return http.HttpResponseForbidden("缺少必传参数")
    #     判断sku_id 是否存在
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return http.HttpResponseForbidden("商品sku_id不存在")
        #判断count是否为数字
        try:
            count = int(count)
        except Exception:
            return http.HttpResponseForbidden("参数count有误")
        #判断selected是否为bool值
        if selected:
            if not isinstance(selected,bool):
                return http.HttpResponseForbidden("参数selected有误")
        #判断用户是否登陆
        user = request.user
        #接收cookie最后的数据
        cookie_secret_str = ""
        if user.is_authenticated:
            #用户已登陆，修改redis购物车
            redis_client = get_redis_connection("carts")
            new_data = {"count":count,"selected":selected}
            redis_client.hset(user.id,sku_id,json.dumps(new_data))
        else:
            #cookie
            #取出cookie
            cookie_str = request.COOKIES.get("carts")
            #2.判断有无  有--解密
            if cookie_str:
                cart_dict = CookieSecret.loads(cookie_str)
            else:
                cart_dict = {}
            # 3.修改dict[k] =count
            cart_dict[sku_id]= {
                "count":count,
                "selected":selected,
            }
            cookie_secret_str = CookieSecret.dumps(cart_dict)
            #构建前端数据格式
            cart_sku = {
                "id":sku_id,
                "count":count,
                "selected":selected,
                "name":sku.name,
                "default_image_url":sku.default_image.url,
                "price":sku.price,
                "amount":sku.price*count,
            }
            response = JsonResponse({"code":RETCODE.OK,"errmsg":"修改购物车成功","cart_sku":cart_sku})
            #未登录 才设置cookie
            if not user.is_authenticated:
                response.set_cookie("carts",cookie_secret_str)
            return response
    #2.查询
    def get(self,request):
        user = request.user
        if user.is_authenticated:
            #从redis里面读取
            # 从redis里面读
            redis_client = get_redis_connection('carts')
            client_data = redis_client.hgetall(user.id)
            print(client_data)

            # carts_dict = {}
            # for data in client_data.items():
            #     # data = (b'3', b'{"count": 4, "selected": true}')
            #     sku_id = int(data[0].decode())
            #     sku_dict = json.loads(data[1].decode())
            #     carts_dict[sku_id]=sku_dict

            carts_dict = {int(data[0].decode()): json.loads(data[1].decode()) for data in client_data.items()}

        else:
            #从cookie取
            #1.获取所有 cookie数据 request.COOKIES
            cookie_str = request.COOKIES.get("carts")
            #1.判断是否有值： 有----解密-----dict
            if cookie_str:
                carts_dict = CookieSecret.loads(cookie_str)
            else:
                carts_dict = {}
        #3.sku_ids = dict.keys()
        sku_ids = carts_dict.keys()

        #4.for sku_id in sku_ids:
        cart_skus = []
        for sku_id in sku_ids:
            #5.根据sku_id取数据库   查询商品信息
            sku = SKU.objects.get(id=sku_id,is_launched=True)
            #6.构造前端的数据格式
            cart_skus.append({
                "id":sku.id,
                "name":sku.name,
                "count":carts_dict.get(sku.id).get("count"),
                "selected":str(carts_dict.get(sku.id).get("selected")),
                "default_image_url":sku.default_image.url,
                "price":str(sku.price),
                "amount":str(sku.price*carts_dict.get(sku.id).get("count")),

            })
        context = {
            "cart_skus":cart_skus
        }
        return render(request,"cart.html",context)
    def post(self, request):
        # 1. 接收参数request.body
        # 接收参数
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')
        count = json_dict.get('count')
        selected = json_dict.get('selected', True)
        # 2. 校验
        #判断参数是否齐全
        if not all([sku_id,count]):
            return http.HttpResponseForbidden("缺少必传参数")
        #判断sku_id是否存在
        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return http.HttpResponseForbidden("商品不存在")
        #判断count 是否为数字
        try:
            count = int(count)
        except Exception:
            return http.HttpResponseForbidden("参数count有误")
        #判断selected是否为bool值
        if selected:
            if not isinstance(selected,bool):
                return http.HttpResponseForbidden("参数selected有误")
        #3. 判断是否登陆
        user = request.user
        if user.is_authenticated:
            #1.获取redis client
            redis_client = get_redis_connection("carts")
            #2.获取当前用户的 所有 购物车数据hgetall()
            client_data = redis_client.hgetall(user.id)
            #3.判断是否存在 如果没有数据  直接新增 hset()
            if not client_data:
                redis_client.hset(user.id,sku_id,json.dumps({"count":count,"selected":selected}))

            # 4.有，修改count 值累加
            if str(sku_id).encode() in client_data:
                sku_dict = json.loads(client_data[str(sku_id).encode()].decode())
                sku_dict["count"] += count
                redis_client.hset(user.id,sku_id,json.dumps(sku_dict))
            else:
            # 5.没有的 新增当前商品的 购物车数据
                redis_client.hset(user.id,sku_id,json.dumps({"count":count,"selected":selected}))

            return JsonResponse({'code':RETCODE.OK,"errmsg":"添加购物车成功"})
        else:
        # 3.2 未登录  cookie
            #1.读取cookie里面值  COOKIES["carts"]
            cookie_str = request.COOKIES.get("carts")
            #2.判断是否有值：有---解密
            if cookie_str:
                carts_dict = CookieSecret.loads(cookie_str)
            else:
                carts_dict = {}
            #3.没有 新增
            if sku_id in carts_dict:
                # 取出 以前存的个数
                original_count = carts_dict[sku_id]["count"]
                count = count + original_count
            # 4.判断当前sku_id以前存过没有，如果有 +=count
            carts_dict[sku_id]={
                "count":count,
                "selected":selected
            }
        #加密
            cookie_secret_str = CookieSecret.dumps(carts_dict)
            response = JsonResponse({'code':RETCODE.OK,"errmsg":"添加 购物车成功"})
            response.set_cookie("carts",cookie_secret_str,max_age=14*24*3600)
            return response

